package sy4_Creational_Pattern.factory.method;
/*
 * 工厂方法模式要点：
 * 简单工厂模式里的工厂类的职责过多（使用了if...else...嵌套，因而不便扩展——增加产品）。因此，
 * 将原来的工厂类拆分成了一个个的工厂类，它们都继承于同一个抽象类。使得新增产品时，只需要
 * 同时创建具体产品类及相应的具体工厂类，而无需修改已有类（测试类除外）。因此，工厂方法模式符合符合OCP原则。
 * 工厂方法模式属于类创建型模式。
 * 
 * 问题：工厂方法模式假定一个具体工厂只生产一种电视产品，还需要研究一个具体工厂生产多种产品的问题。
 * 解决方案：使用抽象工厂模式。
 */

import java.util.Arrays;

abstract class Product {  //角色1：抽象产品
    public abstract void productMethod();
}

class ConcreteProduct extends Product{  //角色2：具体产品
	@Override
    public void productMethod() {
        System.out.println("海尔电视机播放中......");
    }
}
class ConcreteProduct2 extends Product{  //新增产品
	@Override
    public void productMethod() {
        System.out.println("海信电视机播放中......");
    }
}

abstract class Creator {  //角色3：抽象工厂Creator
     public abstract Product factoryMethod();  //电视机工厂生产电视机
}

class ConcreteCreator extends Creator { //角色4：具体工厂ConcreteCreator
	@Override
    public Product factoryMethod() {
        System.out.println("海尔电视机工厂生产海尔电视机。");
        //返回值类型==>ConcreteCreator依赖ConcreteProduct
        return new ConcreteProduct();   
    }
}
class ConcreteCreator2 extends Creator {  //供创建新的产品用
	@Override
    public Product factoryMethod() {
        System.out.println("海信电视机工厂生产海信电视机。");
        return new ConcreteProduct2();
    }
}

public class Client { //客户端
    public static void main(String[] args) {
        //面向抽象编程，提高了程序的灵活性；不使用“XML+Java反射”方式
    	/*Creator creator=new ConcreteCreator();    //可以选择其它的具体创建者
    	Product product=creator.factoryMethod();  //创建产品
    	product.productMethod();   //使用产品方法*/
    	
    	//推荐使用“XML配置文件+Java反射”方式
    	//当新增产品时，只需要同时创建具体产品类及相应的具体工厂类，并对配置文件做相应的修改
    	try {
			Creator creator = (Creator) XMLUtil.getBean(); //强制类型转换
			Product product = creator.factoryMethod(); //调用抽象方法
			product.productMethod(); //调用抽象方法
        } catch (Exception e) {
            System.out.println(e.getMessage());
        }
    }
}